package com.remac.framework.mybatisplus.extensions.enhance.support;

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.remac.framework.mybatisplus.extensions.enhance.IMybatisPlusEnhancer;
import com.remac.framework.mybatisplus.extensions.typehandler.IGenericTypeHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.type.TypeHandler;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Objects;

/**
 * 泛型字段类型处理器增强
 *
 * @author Ye Junhui
 * @since 2024/4/25
 */
@Slf4j
public class GenericTypeHandlerMybatisPlusEnhancer implements IMybatisPlusEnhancer {

    @Override
    public void enhance(MybatisConfiguration mybatisConfiguration) {
        Collection resultMaps = (Collection) mybatisConfiguration.getResultMaps();
        resultMaps.forEach(resultMapObj -> {
            if (!(resultMapObj instanceof ResultMap)){
                return;
            }
            ResultMap resultMap = (ResultMap) resultMapObj;

            //实体类
            Class<?> javaEntityClass = resultMap.getType();

            //映射结果
            resultMap.getResultMappings().forEach(resultMapping -> {
                //字段类型处理器
                TypeHandler<?> typeHandler = resultMapping.getTypeHandler();
                if (Objects.isNull(typeHandler) || !(typeHandler instanceof IGenericTypeHandler)) {
                    return;
                }

                //泛型类型处理器
                IGenericTypeHandler genericTypeHandler = (IGenericTypeHandler) typeHandler;

                //字段名
                String fieldName = resultMapping.getProperty();

                try {
                    Field field = javaEntityClass.getDeclaredField(fieldName);
                    //字段泛型类型
                    Type genericType = field.getGenericType();
                    genericTypeHandler.setType(genericType);
                } catch (Exception e) {
                    log.error("class = {} , field = {} not found cannot enhance", javaEntityClass.getName(), fieldName);
                }
            });
        });
    }
}
